program bezier_curves ;

{$U+}

 const
  numstate = $20 ;

 type
   arr = array[0..20,1..2] of integer ;

 var
   pts : arr ;
   i , n , tx , ty : integer ;
   x , y : real ;
   x1 , y1 , x2 , y2 , flag , ctr : integer ;
   c1 : char ;
   kbflag : byte absolute $0040:$0017 ;

procedure setnum ;
 begin
   kbflag := kbflag or numstate ;
 end ;

procedure resetnum ;
 begin
   kbflag := kbflag and 0 ;
 end ;

function c ( n , i : integer ) : integer ;
 var
   j , a : integer ;
 begin
   a := 1 ;
   for j := (i+1) to n do
      a := a * j ;
   for j := 1 to (n-i) do
      a := a div j ;
   c := a ;
 end ;

function bblend ( i , n : integer ; u : real ) : real ;
 var
   j : integer ;
   v : real ;
 begin
   v := c ( n , i ) ;
   for j := 1 to i do
      v := v * u ;
   for j := 1 to ( n - i ) do
      v := v * ( 1 - u ) ;
   bblend := v ;
 end ;

procedure bezier(var x , y : real ; u : real ; n : integer ) ;
 var
   i : integer ;
   b : real ;
 begin
   x := 0 ;
   y := 0 ;
   for i := 0 to n do
    begin
      b := bblend( i , n , u ) ;
      x := x + pts[i,1] * b ;
      y := y + pts[i,2] * b ;
    end ;
 end ;

procedure move (x , y : integer ) ;
 begin
   tx := x ;
   ty := y ;
 end ;

procedure line(x , y : integer ) ;
 begin
   draw(tx,ty,x,y,3) ;
   tx := x ;
   ty := y ;
 end ;

procedure drawcurve ;
 var
   i : integer ;
   x , y : real ;
 begin
   for i := 0 to 200 do
    begin
      bezier( x , y , i/200 , ctr - 1 ) ;
      if ( i = 0 ) then
        move(round(x),round(y))
      else
        line(round(x),round(y)) ;
    end ;
 end ;


begin
  x1 := 160 ;
  x2 := x1 ;
  y1 := 100 ;
  y2 := y1 ;
  ctr := 0 ;
  graphmode ;
  setnum ;
  c1 := '0' ;
  while ( ord(c1) <> 27 ) do
   begin
    plot(x2,y2,3) ;
    read(kbd,c1) ;
    c1 := upcase(c1) ;
    if ( c1 = 'C' ) then
     begin
       for i := 0 to ( ctr - 2 ) do
          draw(pts[i,1],pts[i,2],pts[i+1,1],pts[i+1,2],3) ;
       drawcurve ;
     end ;
    if ( c1 = 'E' ) then
      ctr := 0 ;
    case c1 of
      '8' : begin
              if ( y2 > 0 ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 y2 := y2 - 1 ;
               end ;
            end ;
      '2' : begin
              if ( y2 < 199 ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 y2 := y2 + 1 ;
               end ;
            end ;
      '4' : begin
              if ( x2 > 0 ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 x2 := x2 - 1 ;
               end ;
            end ;
      '6' : begin
              if ( x2 < 319 ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 x2 := x2 + 1 ;
               end ;
            end ;
      '7' : begin
              if ( ( y2 > 0 ) and ( x2 > 0 ) ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 y2 := y2 - 1 ;
                 x2 := x2 - 1 ;
               end ;
            end ;
      '9' : begin
              if ( ( y2 > 0 ) and ( x2 < 319 ) ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 y2 := y2 - 1 ;
                 x2 := x2 + 1 ;
               end ;
            end ;
      '1' : begin
              if ( ( y2 < 199 ) and ( x2 > 0 ) ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 y2 := y2 + 1 ;
                 x2 := x2 - 1 ;
               end ;
            end ;
      '3' : begin
              if ( ( y2 < 199 ) and ( x2 < 319 ) ) then
               begin
                 if ( flag = 0 ) then
                    plot(x2,y2,0) ;
                 flag := 0 ;
                 y2 := y2 + 1 ;
                 x2 := x2 + 1 ;
               end ;
            end ;
     end ;
   if ( ord(c1) = 13 ) then
    begin
      plot(x2,y2,3) ;
      pts[ctr,1] := x2 ;
      pts[ctr,2] := y2 ;
      flag := 1 ;
      ctr := ctr + 1 ;
      x1 := x2 ;
      y1 := y2 ;
    end ;
  end ;
  resetnum ;
  textmode(bw80) ;
end .
